// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: xguo

#pragma once

#include <string>

#include <rapidjson/document.h>

#include "coin/proto/coin_query.pb.h"

namespace coin2::exchange::okex::order_v3 {

namespace error_code {

inline int32_t GetErrorCodeAsInt(
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json_error_code) {
  int32_t error_code = 0;
  if (json_error_code.IsInt()) {
    error_code = json_error_code.GetInt();
  } else if (json_error_code.IsString() && std::strlen(json_error_code.GetString()) > 0) {
    error_code = std::stoi(json_error_code.GetString());
  }
  return error_code;
}

inline std::string GetExchangeOrderErrorCode(
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json) {
  if (json.HasMember("error_code")) {
    return std::to_string(GetErrorCodeAsInt(json["error_code"]));
  } else {
    return {};
  }
}

inline std::string GetExchangeOrderErrorMsg(
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json) {
  if (json.HasMember("error_message")) {
    return json["error_message"].GetString();
  } else {
    return {};
  }
}

inline coin::proto::OrderErrorCode GetOrderErrorCode(
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json_error_code) {
  using coin::proto::OrderErrorCode;
  auto result = coin::proto::OrderErrorCode::ORDER_UNKNOWN_ERROR;
  int32_t error_code = GetErrorCodeAsInt(json_error_code);

  // 32xxx futures
  // 33xxx spot
  // 35xxx swap
  if (error_code == 0) {
    result = OrderErrorCode::ORDER_NO_ERROR;
  } else if (error_code == 30044) {
    result = OrderErrorCode::ORDER_UNCERTAIN;
  } else if (error_code == 32004) {
    result = OrderErrorCode::ORDER_ON_THE_FLY;
  } else if (error_code == 32014) {
    result = OrderErrorCode::SUBMIT_ORDER_INSUFFICIENT_POSITION;
  } else if (error_code == 32015) {
    result = OrderErrorCode::SUBMIT_ORDER_INSUFFICIENT_FUND;
  } else if (error_code == 32016) {
    result = OrderErrorCode::SUBMIT_ORDER_INSUFFICIENT_FUND;
  } else if (error_code == 32024) {  // delivery time
    result = OrderErrorCode::TRADING_HALT;
  } else if (error_code == 32025) {  // settlement time
    result = OrderErrorCode::TRADING_HALT;
  } else if (error_code == 33017) {
    result = OrderErrorCode::SUBMIT_ORDER_INSUFFICIENT_FUND;
  } else if (error_code == 33014) {
    result = OrderErrorCode::ORDER_ON_THE_FLY;
  } else if (error_code == 33026) {
    result = OrderErrorCode::ORDER_FILLED_ALREADY;
  } else if (error_code == 33027) {  // canceled or cancelling
    // result = OrderErrorCode::ORDER_CANCELED_ALREADY;
  } else if (error_code == 35010) {
    result = OrderErrorCode::SUBMIT_ORDER_INSUFFICIENT_POSITION;
  } else if (error_code == 35039) {
    result = OrderErrorCode::SUBMIT_ORDER_INSUFFICIENT_FUND;
  } else if (error_code == 35044) {
    result = OrderErrorCode::ORDER_FILLED_ALREADY;
  } else if (error_code == 35055) {
    result = OrderErrorCode::SUBMIT_ORDER_INSUFFICIENT_FUND;
  }

  return result;
}

}  // namespace error_code

}  // namespace coin2::exchange::okex::order_v3

